package com.zhuoya.healthcard.util;

import java.io.*;

public class Base64Utils {
    public static final int CRLF = 4;
    public static final int DEFAULT = 0;
    public static final int NO_CLOSE = 16;
    public static final int NO_PADDING = 1;
    public static final int NO_WRAP = 2;
    public static final int URL_SAFE = 8;

    public static byte[] decode(final String s, final int n) throws IllegalArgumentException {
        return decode(s.getBytes(), n);
    }

    public static byte[] decode(final byte[] array, final int n) throws IllegalArgumentException {
        return decode(array, 0, array.length, n);
    }

    public static byte[] decode(byte[] array, final int n, final int n2, final int n3) throws IllegalArgumentException {
        final Decoder decoder = new Decoder(n3, new byte[n2 * 3 / 4]);
        if (!decoder.process(array, n, n2, true)) {
            throw new IllegalArgumentException("bad base-64");
        }
        if (decoder.op == decoder.output.length) {
            return decoder.output;
        }
        array = new byte[decoder.op];
        System.arraycopy(decoder.output, 0, array, 0, decoder.op);
        return array;
    }

    public static byte[] encode(final byte[] array, final int n) {
        return encode(array, 0, array.length, n);
    }

    public static byte[] encode(final byte[] array, final int n, final int n2, int n3) {
        final Encoder encoder = new Encoder(n3, null);
        final int n4 = n2 / 3 * 4;
        final boolean do_padding = encoder.do_padding;
        final int n5 = 2;
        if (do_padding) {
            n3 = n4;
            if (n2 % 3 > 0) {
                n3 = n4 + 4;
            }
        } else {
            n3 = n2 % 3;
            if (n3 != 0) {
                if (n3 != 1) {
                    if (n3 != 2) {
                        n3 = n4;
                    } else {
                        n3 = n4 + 3;
                    }
                } else {
                    n3 = n4 + 2;
                }
            } else {
                n3 = n4;
            }
        }
        int n6 = n3;
        if (encoder.do_newline) {
            n6 = n3;
            if (n2 > 0) {
                final int n7 = (n2 - 1) / 57;
                int n8;
                if (encoder.do_cr) {
                    n8 = n5;
                } else {
                    n8 = 1;
                }
                n6 = n3 + (n7 + 1) * n8;
            }
        }
        encoder.output = new byte[n6];
        encoder.process(array, n, n2, true);
        return encoder.output;
    }

    public static String encodeToString(final byte[] array, final int n) {
        try {
            return new String(encode(array, n), "US-ASCII");
        } catch (UnsupportedEncodingException ex) {
            throw new AssertionError((Object) ex);
        }
    }

    public static String encodeToString(final byte[] array, final int n, final int n2, final int n3) {
        try {
            return new String(encode(array, n, n2, n3), "US-ASCII");
        } catch (UnsupportedEncodingException ex) {
            throw new AssertionError((Object) ex);
        }
    }

    abstract static class Coder {
        public int op;
        public byte[] output;

        public abstract int maxOutputSize(final int p0);

        public abstract boolean process(final byte[] p0, final int p1, final int p2, final boolean p3);
    }

    static class Decoder extends Coder {
        private static final int[] DECODE;
        private static final int[] DECODE_WEBSAFE;
        private static final int EQUALS = -2;
        private static final int SKIP = -1;
        private final int[] alphabet;
        private int state;
        private int value;

        static {
            DECODE = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
            DECODE_WEBSAFE = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
        }

        public Decoder(final int n, final byte[] output) {
            this.output = output;
            int[] alphabet;
            if ((n & 0x8) == 0x0) {
                alphabet = Decoder.DECODE;
            } else {
                alphabet = Decoder.DECODE_WEBSAFE;
            }
            this.alphabet = alphabet;
            this.state = 0;
            this.value = 0;
        }

        @Override
        public int maxOutputSize(final int n) {
            return n * 3 / 4 + 10;
        }

        @Override
        public boolean process(final byte[] array, int n, int value, final boolean b) {
            if (this.state == 6) {
                return false;
            }
            int n2 = n;
            final int n3 = value + n;
            int state = this.state;
            value = this.value;
            n = 0;
            final byte[] output = this.output;
            final int[] alphabet = this.alphabet;
            int value2;
            int n4;
            while (true) {
                value2 = value;
                n4 = n;
                if (n2 >= n3) {
                    break;
                }
                int n5 = n2;
                int n6 = value;
                int n7 = n;
                if (state == 0) {
                    while (n2 + 4 <= n3) {
                        final int n8 = alphabet[array[n2] & 0xFF] << 18 | alphabet[array[n2 + 1] & 0xFF] << 12 | alphabet[array[n2 + 2] & 0xFF] << 6 | alphabet[array[n2 + 3] & 0xFF];
                        final int n9 = value = n8;
                        if (n8 < 0) {
                            break;
                        }
                        output[n + 2] = (byte) n9;
                        output[n + 1] = (byte) (n9 >> 8);
                        output[n] = (byte) (n9 >> 16);
                        n += 3;
                        n2 += 4;
                        value = n9;
                    }
                    n5 = n2;
                    n6 = value;
                    n7 = n;
                    if (n2 >= n3) {
                        value2 = value;
                        n4 = n;
                        break;
                    }
                }
                final int n10 = alphabet[array[n5] & 0xFF];
                if (state != 0) {
                    if (state != 1) {
                        if (state != 2) {
                            if (state != 3) {
                                if (state != 4) {
                                    if (state != 5) {
                                        n = state;
                                        value = n6;
                                    } else {
                                        n = state;
                                        value = n6;
                                        if (n10 != -1) {
                                            this.state = 6;
                                            return false;
                                        }
                                    }
                                } else if (n10 == -2) {
                                    n = state + 1;
                                    value = n6;
                                } else {
                                    n = state;
                                    value = n6;
                                    if (n10 != -1) {
                                        this.state = 6;
                                        return false;
                                    }
                                }
                            } else if (n10 >= 0) {
                                value = (n6 << 6 | n10);
                                output[n7 + 2] = (byte) value;
                                output[n7 + 1] = (byte) (value >> 8);
                                output[n7] = (byte) (value >> 16);
                                n7 += 3;
                                n = 0;
                            } else if (n10 == -2) {
                                output[n7 + 1] = (byte) (n6 >> 2);
                                output[n7] = (byte) (n6 >> 10);
                                n7 += 2;
                                n = 5;
                                value = n6;
                            } else {
                                n = state;
                                value = n6;
                                if (n10 != -1) {
                                    this.state = 6;
                                    return false;
                                }
                            }
                        } else if (n10 >= 0) {
                            value = (n6 << 6 | n10);
                            n = state + 1;
                        } else if (n10 == -2) {
                            output[n7] = (byte) (n6 >> 4);
                            n = 4;
                            ++n7;
                            value = n6;
                        } else {
                            n = state;
                            value = n6;
                            if (n10 != -1) {
                                this.state = 6;
                                return false;
                            }
                        }
                    } else if (n10 >= 0) {
                        value = (n6 << 6 | n10);
                        n = state + 1;
                    } else {
                        n = state;
                        value = n6;
                        if (n10 != -1) {
                            this.state = 6;
                            return false;
                        }
                    }
                } else if (n10 >= 0) {
                    value = n10;
                    n = state + 1;
                } else {
                    n = state;
                    value = n6;
                    if (n10 != -1) {
                        this.state = 6;
                        return false;
                    }
                }
                n2 = n5 + 1;
                state = n;
                n = n7;
            }
            if (!b) {
                this.state = state;
                this.value = value2;
                this.op = n4;
                return true;
            }
            if (state != 0) {
                if (state == 1) {
                    this.state = 6;
                    return false;
                }
                if (state != 2) {
                    if (state != 3) {
                        if (state == 4) {
                            this.state = 6;
                            return false;
                        }
                    } else {
                        n = n4 + 1;
                        output[n4] = (byte) (value2 >> 10);
                        n4 = n + 1;
                        output[n] = (byte) (value2 >> 2);
                    }
                } else {
                    output[n4] = (byte) (value2 >> 4);
                    ++n4;
                }
            }
            this.state = state;
            this.op = n4;
            return true;
        }
    }

    static class Encoder extends Coder {
        private static final byte[] ENCODE;
        private static final byte[] ENCODE_WEBSAFE;
        public static final int LINE_GROUPS = 19;
        private final byte[] alphabet;
        private int count;
        public final boolean do_cr;
        public final boolean do_newline;
        public final boolean do_padding;
        private final byte[] tail;
        int tailLen;

        static {
            ENCODE = new byte[]{65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47};
            ENCODE_WEBSAFE = new byte[]{65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95};
        }

        public Encoder(int count, byte[] array) {
            this.output = array;
            final boolean b = true;
            this.do_padding = ((count & 0x1) == 0x0);
            this.do_newline = ((count & 0x2) == 0x0);
            this.do_cr = ((count & 0x4) != 0x0 && b);
            if ((count & 0x8) == 0x0) {
                array = Encoder.ENCODE;
            } else {
                array = Encoder.ENCODE_WEBSAFE;
            }
            this.alphabet = array;
            this.tail = new byte[2];
            this.tailLen = 0;
            if (this.do_newline) {
                count = 19;
            } else {
                count = -1;
            }
            this.count = count;
        }

        @Override
        public int maxOutputSize(final int n) {
            return n * 8 / 5 + 10;
        }

        @Override
        public boolean process(byte[] array, int n, int tailLen, final boolean b) {
            final byte[] alphabet = this.alphabet;
            final byte[] output = this.output;
            final int n2 = 0;
            final int count = this.count;
            final int n3 = tailLen + n;
            int n4 = -1;
            tailLen = this.tailLen;
            int n5 = 0;
            Label_0183:
            {
                if (tailLen != 0) {
                    if (tailLen != 1) {
                        if (tailLen == 2) {
                            if (n + 1 <= n3) {
                                final byte[] tail = this.tail;
                                tailLen = tail[0];
                                final byte b2 = tail[1];
                                n5 = n + 1;
                                n4 = ((b2 & 0xFF) << 8 | (tailLen & 0xFF) << 16 | (array[n] & 0xFF));
                                this.tailLen = 0;
                                break Label_0183;
                            }
                        }
                    } else if (n + 2 <= n3) {
                        final byte b3 = this.tail[0];
                        tailLen = n + 1;
                        n4 = ((array[n] & 0xFF) << 8 | (b3 & 0xFF) << 16 | (array[tailLen] & 0xFF));
                        this.tailLen = 0;
                        n5 = tailLen + 1;
                        break Label_0183;
                    }
                }
                n5 = n;
            }
            n = n2;
            tailLen = count;
            int n6 = n5;
            if (n4 != -1) {
                tailLen = 0 + 1;
                output[0] = alphabet[n4 >> 18 & 0x3F];
                n = tailLen + 1;
                output[tailLen] = alphabet[n4 >> 12 & 0x3F];
                tailLen = n + 1;
                output[n] = alphabet[n4 >> 6 & 0x3F];
                final int n7 = tailLen + 1;
                output[tailLen] = alphabet[n4 & 0x3F];
                final int n8 = count - 1;
                n = n7;
                tailLen = n8;
                n6 = n5;
                if (n8 == 0) {
                    n = n7;
                    if (this.do_cr) {
                        output[n7] = 13;
                        n = n7 + 1;
                    }
                    output[n] = 10;
                    tailLen = 19;
                    ++n;
                    n6 = n5;
                }
            }
            while (n6 + 3 <= n3) {
                final int n9 = (array[n6] & 0xFF) << 16 | (array[n6 + 1] & 0xFF) << 8 | (array[n6 + 2] & 0xFF);
                output[n] = alphabet[n9 >> 18 & 0x3F];
                output[n + 1] = alphabet[n9 >> 12 & 0x3F];
                output[n + 2] = alphabet[n9 >> 6 & 0x3F];
                output[n + 3] = alphabet[n9 & 0x3F];
                final int n10 = n6 + 3;
                final int n11 = n + 4;
                final int n12 = tailLen - 1;
                n = n11;
                tailLen = n12;
                n6 = n10;
                if (n12 == 0) {
                    n = n11;
                    if (this.do_cr) {
                        output[n11] = 13;
                        n = n11 + 1;
                    }
                    output[n] = 10;
                    tailLen = 19;
                    ++n;
                    n6 = n10;
                }
            }
            int op;
            if (b) {
                final int tailLen2 = this.tailLen;
                int n19;
                if (n6 - tailLen2 == n3 - 1) {
                    byte b4;
                    int n14;
                    if (tailLen2 > 0) {
                        array = this.tail;
                        final int n13 = 0 + 1;
                        b4 = array[0];
                        n14 = n13;
                    } else {
                        b4 = array[n6];
                        n14 = 0;
                    }
                    final int n15 = (b4 & 0xFF) << 4;
                    this.tailLen -= n14;
                    final int n16 = n + 1;
                    output[n] = alphabet[n15 >> 6 & 0x3F];
                    final int n17 = n16 + 1;
                    output[n16] = alphabet[n15 & 0x3F];
                    n = n17;
                    if (this.do_padding) {
                        final int n18 = n17 + 1;
                        output[n17] = 61;
                        n = n18 + 1;
                        output[n18] = 61;
                    }
                    n19 = n;
                    if (this.do_newline) {
                        int n20 = n;
                        if (this.do_cr) {
                            output[n] = 13;
                            n20 = n + 1;
                        }
                        output[n20] = 10;
                        n19 = n20 + 1;
                    }
                } else if (n6 - tailLen2 == n3 - 2) {
                    int n21 = 0;
                    byte b5;
                    if (tailLen2 > 1) {
                        b5 = this.tail[0];
                        n21 = 0 + 1;
                    } else {
                        final int n22 = n6 + 1;
                        b5 = array[n6];
                        n6 = n22;
                    }
                    int n24;
                    int n25;
                    if (this.tailLen > 0) {
                        array = this.tail;
                        final int n23 = n21 + 1;
                        n24 = array[n21];
                        n25 = n23;
                    } else {
                        final byte b6 = array[n6];
                        n25 = n21;
                        n24 = b6;
                    }
                    final int n26 = (n24 & 0xFF) << 2 | (b5 & 0xFF) << 10;
                    this.tailLen -= n25;
                    final int n27 = n + 1;
                    output[n] = alphabet[n26 >> 12 & 0x3F];
                    final int n28 = n27 + 1;
                    output[n27] = alphabet[n26 >> 6 & 0x3F];
                    n = n28 + 1;
                    output[n28] = alphabet[n26 & 0x3F];
                    if (this.do_padding) {
                        final int n29 = n + 1;
                        output[n] = 61;
                        n = n29;
                    }
                    n19 = n;
                    if (this.do_newline) {
                        int n30 = n;
                        if (this.do_cr) {
                            output[n] = 13;
                            n30 = n + 1;
                        }
                        output[n30] = 10;
                        n19 = n30 + 1;
                    }
                } else {
                    n19 = n;
                    if (this.do_newline && (n19 = n) > 0) {
                        n19 = n;
                        if (tailLen != 19) {
                            int n31 = n;
                            if (this.do_cr) {
                                output[n] = 13;
                                n31 = n + 1;
                            }
                            output[n31] = 10;
                            n19 = n31 + 1;
                        }
                    }
                }
                op = n19;
            } else if (n6 == n3 - 1) {
                this.tail[this.tailLen++] = array[n6];
                op = n;
            } else {
                op = n;
                if (n6 == n3 - 2) {
                    final byte[] tail2 = this.tail;
                    tail2[this.tailLen++] = array[n6];
                    tail2[this.tailLen++] = array[n6 + 1];
                    op = n;
                }
            }
            this.op = op;
            this.count = tailLen;
            return true;
        }
    }
}
